import * as THREE from '../lab/three.weapp.js';
import { OrbitControls } from '../lab/OrbitControls.js';
import gLTF from "../lab/GLTFLoader.js";

let canvas;
let camera;
let scene;
let renderer;

const GLTFLoader = gLTF(THREE);

let cameraControls,animationId,canvasId;
let markCupModel;
let material;
let zero = new THREE.Vector3(0,0,0);
let setInfo = ()=>{};

// 初始化three
export const initThree = async (id) => {
  await new Promise((res, rej)=>{
    wx.createSelectorQuery().select(id).node().exec((dom)=>{
      canvasId = dom[0].node._canvasId;
      canvas = THREE.global.registerCanvas(canvasId, dom[0].node);
      res(true);
    });
  });
  return true;
}

// 初始化3要素
export const init3Boss = () => {
  camera = new THREE.PerspectiveCamera(75, canvas.width/canvas.height, 0.1, 1000);
  camera.position.set(0,0,-25);
  camera.lookAt(zero);
  scene = new THREE.Scene();

  renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);

  wx.onWindowResize(onWindowResize);
}

// 测试 - 创建box
let boxG,boxM,boxC;
export const initBox = () => {
   boxG = new THREE.BoxGeometry( 1, 1, 1 );
   boxM = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
   boxC = new THREE.Mesh( boxG, boxM );
  scene.add( boxC );
}

export const clearBox = () => {
  boxM.dispose();
  boxG.dispose();
  boxC = null;
}

// 窗口改变时触发
export const onWindowResize = (result) => {
  camera.aspect = result.windowWidth / result.windowHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(canvas.width, canvas.height);
}

// 辅助对象
export const initHelper = () => {
  console.log('初始化Helper');

  // 三位坐标轴
  // scene.add(new THREE.AxesHelper(20));

  // 环境光
  const light = new THREE.AmbientLight( 0xaaaaaa );
  scene.add( light );

  // 平行光
  let directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
  directionalLight.position.set(1,1,1);
  // directionalLight.castShadow = true; //关键
  scene.add( directionalLight );
  let directionalLight2 = new THREE.DirectionalLight( 0xffffff, 0.4 );
  scene.add(directionalLight2);
  directionalLight2.position.set(2,-4,2);

  console.log('Helper初始化完毕');
}

// 初始化镜头控制器
export const initOrbitControl = () => {
  cameraControls = new OrbitControls(camera, renderer.domElement);
  cameraControls.target.set(0, 0, 0);
  cameraControls.maxDistance = 6;
  cameraControls.minDistance = 4;
  cameraControls.enableDamping = true;
  cameraControls.enableKeys = false;
  cameraControls.enablePan = false;
  cameraControls.maxPolarAngle = Math.PI * 0.8;
  cameraControls.minPolarAngle = Math.PI * 0.1;
  cameraControls.update();
}

// 加载6张图，制作环境贴图
  // skybox1
  const urls = [
  [
    "https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox/posx.jpg?sign=4c5a8aafd84178eb24a7539ad6e0c415&t=1621393276", // px
    "https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox/negx.jpg?sign=ced4b41e74872b6642d04684b61c4832&t=1621393289", // nx
    "https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox/posy.jpg?sign=934cd52f01a90d4293ad5603472fe798&t=1621393299", // py
    "https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox/negy.jpg?sign=b98970ed61b727c7e23b169215f32707&t=1621393309", // ny
    "https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox/posz.jpg?sign=7d6dd18175f9d2a84fd5b7e487f7c908&t=1621393321", // pz
    "https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox/negz.jpg?sign=bc279452af16fb76c9ec832bab604784&t=1621393331", // nz
  ],
  [
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox2/px.jpg?sign=5adbc7e02a93d286e67fefd552e80b8c&t=1621491948',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox2/nx.jpg?sign=3d2c4f6485116bb8ba5be15aa654e7b6&t=1621491963',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox2/py.jpg?sign=5562249ae24621bb1f79b0f0980f044b&t=1621491975',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox2/ny.jpg?sign=e8b011b85497ddb8148d5b22d751cbd5&t=1621491988',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox2/pz.jpg?sign=7f8107900af053de3c24f770dee50e3a&t=1621492003',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox2/nz.jpg?sign=bf5a893facb17357df45197c40f035b0&t=1621492016'
  ],
  [
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox3/px.jpg?sign=84be53aeda19d24c2c2d562b2f96af7f&t=1621492634',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox3/nx.jpg?sign=bfe09718c85570cbfd2b4957fcb25911&t=1621492646',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox3/py.jpg?sign=3a6b574fd562ce04caf3a0312567988b&t=1621492662',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox3/ny.jpg?sign=2fdf8f321f7a4703aca5f576b56fae6a&t=1621492673',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox3/pz.jpg?sign=151b68cf8f00b0cda386c7f1346d6934&t=1621492683',
    'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/skybox3/nz.jpg?sign=4b48455d1fbf198c147bdbe54b9f53f7&t=1621492695'
  ]
];

export const createCubeTexture = (type, skybox = 0) => {
  console.log('初始化天空盒');
  console.time();

  new THREE.CubeTextureLoader().load( urls[skybox], ( cubeTexture ) => {
    cubeTexture.encoding = THREE.sRGBEncoding;
    scene.background = cubeTexture;
    console.log('天空盒图片加载完毕');
    console.timeEnd();
    loadModel(type, cubeTexture);
  });
}

// 清理 卸载对象
export const clear = () => {
  markCupModel.dispose();
  cameraControls.dispose();
  renderer.dispose();
  THREE.global.clearCanvas();
  THREE.global.unregisterCanvas(canvasId);
  wx.offWindowResize(onWindowResize);
  stopClock();
  i = 50;
  scene = null;
  canvas = null;
  if(material){
    material.dispose();
    material = null;
  }
  if(animateMixer){
    animateMixer.stopAllAction();
    animateMixer = null;
  }
}

export const touchStart = (e) => {
  THREE.global.touchEventHandlerFactory('canvas', 'touchstart')(e);
}
export const touchMove = (e) => {
  THREE.global.touchEventHandlerFactory('canvas', 'touchmove')(e);
}
export const touchEnd = (e) => {
  THREE.global.touchEventHandlerFactory('canvas', 'touchend')(e);
}

// 时钟
let clock;
export const initClock = () => {
  clock = new THREE.Clock();
}
export const stopClock = () => {
  if(clock){
    clock.stop();
    clock = null;
  }
}

// 绘制一帧
let i=50;
export const draw = () => {
  if(isMarkOk && i>0){
    i--;
    let r = 6 + i * 0.4;
    let angle = 90 + i * 3.6;
    let x1 = r * Math.cos(angle * Math.PI/180);
    let y1 = r * Math.sin(angle * Math.PI/180);
    camera.position.set(x1,0,y1);
    camera.lookAt(zero);
  }
  renderer.render( scene, camera );
}

// 动画循环
export const animate = () => {
    animationId = canvas.requestAnimationFrame(animate);
    draw();
}

// 取消动画
export const cancelAnimate = () => {
  canvas.cancelAnimationFrame(animationId);
  animationId = null;
}

// 重新开始动画
export const reStartAnimate = () => {
  if(!animationId){
    animate();
  }
}

const loadModel = (type, cubeTexture) => {
  let params;
  switch(type){
    case 'mark': 
      params = {
        url: 'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/mark/scene.gltf',
        envMap: cubeTexture,
        envMapIntensity: 5.0,
        roughness: 0.3,
        maetalness: 0.1,
        needCenter: true,
        rotation:[0,Math.PI,0],
        position:[0.2,-1.2,0],
        scale:[1,1,1]
      };
    break;
    case 'cup': 
      params = {
        url: 'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/cup/scene.gltf',
        envMap: cubeTexture,
        envMapIntensity: 5.0,
        roughness: 0.3,
        maetalness: 0.1,
        needCenter: false,
        rotation:[0,0,0],
        position:[-0.2,-3,0],
        scale: [0.8,0.8,0.8]
      };
      break;
    case 'glass':
      material = new THREE.MeshPhongMaterial({
        color: '#ffffff',
        transparent: true,
        opacity: 0.6,
        shininess: 200, // phone材质独有，高光度，默认30
        depthWrite: false,
        alphaTest: 0.5,
        envMap: cubeTexture,
        envMapIntensity: 2.0,
      });

      params = {
        url: 'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/glass/scene.gltf',
        needCenter: true,
        material,
        rotation:[0,0,0],
        position:[0,0,0],
        scale: [1,1,1]
      }
      break;
    case 'animate':
      params = {
        url: 'https://636c-cloud1-2gdbpqei566f127f-1305722077.tcb.qcloud.la/animate/scene.gltf',
        // envMap: cubeTexture,
        // envMapIntensity: 1.0,
        roughness: 0.3,
        maetalness: 0.1,
        needCenter: true,
        rotation:[0,0,0],
        position:[0,0,0],
        scale: [1,1,1],
        isAnimate: true,
      }
      break;
    case 'box':
      initBox();
      return;
  }
    loadModalMark(params);
}

// 加载模型
let isMarkOk = false;
export const loadModalMark = (params) => {
  // 初始化加载器
  const gltfLoader = new GLTFLoader();
  gltfLoader.load(params.url, (gltf)=>{
    // 得到模型原始对象
    markCupModel = gltf.scene;
    markCupModel.traverse((child) => {
      if (child instanceof THREE.Mesh) {
        child.geometry.normalizeNormals();
        if(params.center){
          child.geometry.center();
        }
        if(params.material){
          child.material = params.material;
        } else {
          child.material.flatShading = false; // 采用快速着色，面速很低
          child.material.envMap = params.envMap || null; // 是否拥有环境贴图
          child.material.envMapIntensity = params.envMapIntensity || 0; // 反射度
          child.material.roughness = params.roughness; // 粗糙度
          child.material.maetalness = params.maetalness; // 金属质感
        }
          child.material.needsUpdate = true; // 需要更新

          if(params.needCenter){
            child.geometry.computeBoundingBox();
            child.geometry.center();
          }
        }
    });
    markCupModel.rotation.set(...params.rotation);
    markCupModel.position.set(...params.position);
    markCupModel.scale.set(...params.scale);
    
    scene.add(markCupModel);
    isMarkOk = true;
    console.log('模型加载完毕：', markCupModel);

    if(params.isAnimate){
      initAnimations(gltf);
    }

  },(p)=>{
    setInfo(JSON.stringify(p));
  }, (err)=>{
    setInfo(JSON.stringify(err));
  });
}

// 测试写入信息
export const setInfoCallback = (callback) => {
  setInfo = callback;
}

/** 处理所有动画 **/
let animations; // 模型拥有的所有动画
let animateMixer; // 动画混合器
let animateNo = 0; // 当前播放的哪一个动画
let action; // 当前操作的动作对象
export const initAnimations = (gltf) => {
  animations = gltf.animations;
  console.log('数组？', animations.length);
  animateMixer = new THREE.AnimationMixer(gltf.scene);

  // 监听动画播放结束，开始下一个动画，循环模式是LoopOnce时才会触发
  animateMixer.addEventListener('finished', (e) => {
    console.log('结束？', animateNo);
    animateNo = animateNo >= animations.length - 1 ? 0 : animateNo + 1;
    playAnimations(animations[animateNo]);
  });
  // 每一个循环结束，触发一次，循环模式不是LoopOnce时有效
  animateMixer.addEventListener('loop', (e) => {
    console.log('loop结束：', e);
    action.stop();
    animateNo = animateNo >= animations.length - 1 ? 0 : animateNo + 1;
    playAnimations(animations[animateNo]);
  });
  playAnimations(animations[animateNo]);
}

/** 执行特定动画 **/
function playAnimations(clip){
  console.log('校验',clip.validate());

  action = animateMixer.clipAction(clip);
  console.log('action', action);
  action.clampWhenFinished = true; // 动作完成时是否保持最后一帧动作
  // action.loop = THREE.LoopOnce; // 循环的次数
  // action.reset();

  
  action.play();
  console.log('开始动画', action);
}

export default {
  init3Boss,
  initThree,
  initHelper,
  initBox,
  clearBox,
  initOrbitControl,
  onWindowResize,
  touchStart,
  touchMove,
  touchEnd,
  animate,
  cancelAnimate,
  reStartAnimate,
  createCubeTexture,
  loadModalMark,
  clear,
  initClock,
  setInfoCallback
}